package com.xhwl.centiotdata.suppliersystem.haikangyunmou;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.constant.HaiKangYunMouConstant;
import com.xhwl.centiotdata.pojo.dto.haikangyunmou.CommunityEventAccess;
import com.xhwl.centiotdata.pojo.dto.haikangyunmou.HaiKangYunMouDevice;
import com.xhwl.centiotdata.pojo.dto.haikangyunmou.HaiKangYunMouProject;
import com.xhwl.centiotdata.pojo.dto.haikangyunmou.MQConsumerMessagesDTO;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.utils.LocalDateTimeUtils;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.constant.cent.alarm.AlarmConstant;
import com.xhwl.common.constant.cent.pedes.PedestrianConstant;
import com.xhwl.common.dto.cent.pedes.OpenDoorRecordDTO;
import com.xhwl.common.enums.AccessApproachEnum;
import com.xhwl.common.enums.AccessTypeEnum;
import com.xhwl.common.enums.DirectionEnum;
import com.xhwl.common.enums.SourceTypeEnum;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author： guan
 * @Description： 海康云眸
 * @Date 2021/09/03/ 09:44
 */
@Slf4j
@Service
public class PedestrianHaiKangYunMouHandler {

    @Resource
    private HaiKangYunMouUtils haiKangYunMouUtils;


    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    public RedisTemplate redisTemplate;

    @Autowired
    private GeneralProducer generalProducer;

    /**
     * 拉取海康云眸人行记录/推送告警
     * @param config
     * @return
     */
    public void pullRecord(PedestrianIntegrationConfigDTO config) {
        Map<String, Integer> map = null;
        if (!StringUtils.isEmpty(config.getOrgIndexCode())) {
            map = handleConfigProjectId(config);
            log.info("[获取到的map]"+JSONObject.toJSONString(map));
        }
        List<MQConsumerMessagesDTO> mqMsg = getMQMsg(config);
        if (CollectionUtils.isEmpty(mqMsg)) {
            return;
        }
        log.info("拉取海康云眸MQ:{}", JSONObject.toJSONString(mqMsg));

        for (MQConsumerMessagesDTO msg : mqMsg) {
            // 为了解决content转义符
            String content = msg.getContent();
            String body = JSONObject.toJSONString(content);
            Object contentObj = JSON.parse(body);
            String contentStr = contentObj.toString();
            CommunityEventAccess cea = JSONObject.parseObject(contentStr, CommunityEventAccess.class);

            Integer projectId = null;
            if (map != null) {
                projectId = map.get(cea.getCommunityId());
            }
            if (projectId == null) {
                log.info("[未获取到projectId]",projectId);
                continue;
            }
            // 推送告警消息
            if (msg.getMsgType().equals(HaiKangYunMouConstant.COMMUNITY_EVENT_ALARM)) {
                Map<String, String> codeMap = redisTemplate.opsForHash().entries(RedisUtils.format(config.getProductId()));
                if (cea.getEventType().equals(HaiKangYunMouConstant.ALARM_EVENT)) {
                    String deviceKey = HaiKangYunMouConstant.DEVICE + cea.getDeviceId();
                    Integer deviceId = (Integer) redisUtils.get(deviceKey);
                    if (deviceId == null) {
                        List<String> communityIds = haiKangYunMouUtils.getCommunityId(config);
                        if (StringUtils.isEmpty(communityIds)) {
                            continue;
                        }
                        List<HaiKangYunMouDevice> devices = new ArrayList<>();
                        communityIds.forEach(communityId ->{
                            devices.addAll(haiKangYunMouUtils.getDevices(config, communityId));
                        });

                        if (CollectionUtils.isEmpty(devices)) {
                            continue;
                        } else {
                            haiKangYunMouUtils.mapThirdDeviceId(projectId, config.getProductId(), devices);
                        }
                        deviceId = (Integer) redisUtils.get(deviceKey);
                        if (deviceId == null) {
                            continue;
                        }
                    }
                    AlarmManagement alarmManagement = new AlarmManagement();
                    alarmManagement.setProjectId(projectId);
                    alarmManagement.setDeviceId(deviceId);
                    alarmManagement.setAlarmInventoryCode(codeMap.get(cea.getEventCode()));
                    alarmManagement.setContent(cea.getEventDescription());
                    // 告警的不带T
                    Date date = LocalDateTimeUtils.getStrCoverDate(cea.getDateTime());
                    alarmManagement.setAlarmTime(date);
                    alarmManagement.setImgUrl(cea.getPictureURL());
                    log.debug("海康云眸推送人行告警：{}", JSONObject.toJSONString(alarmManagement));
                    generalProducer.send(AlarmConstant.ALARM_TOPIC, alarmManagement);
                }
                continue;
            }

            // 出入记录
            if (!msg.getMsgType().equals(HaiKangYunMouConstant.COMMUNITY_EVENT_ACCESS)) {
                continue;
            }
            if (!cea.getEventType().equals(HaiKangYunMouConstant.ACCESS_EVENT)) {
                continue;
            }
            OpenDoorRecordDTO dto = OpenDoorRecordDTO.builder()
                    // 记录唯一标识
                    .code(cea.getEventId())
                    .projectId(projectId)
                    .openDeviceId(cea.getDeviceId())
                    .deviceName(cea.getDeviceName())
                    .sourceType(handlerSourceType(cea.getEventCode()))
                    .arrivalTime(LocalDateTimeUtils.getDateStrRemoveT(cea.getDateTime()))
                    .state((short) 1)
                    // AccessTypeEnum 出入方式出来communityEventAccess.getEventCode()
                    .type(handleRecordType(cea.getEventCode()))
                    // DirectionEnum 出入方向
                    .direction(DirectionEnum.IN.getId())
                    // AccessApproachEnum 出入途径
                    .approach(AccessApproachEnum.OFF_LINE.getId())
                    .openUserId(cea.getPersonId())
                    .userName(cea.getPersonName())
                    .pictureUrl(cea.getPictureURL())
                    .build();

            // 推送人行记录
            log.info("海康云眸推送人行记录：{}", JSONObject.toJSONString(dto));
            generalProducer.send(PedestrianConstant.ACCESS_RECORD_TOPIC, dto);
        }
    }

    private Integer handlerSourceType(String openType){
        switch (openType) {
            //二维码
            case "10122":
                return SourceTypeEnum.VISITOR_USER.getType();
            default:
                return SourceTypeEnum.USER.type;
        }
    }

    /**
     * 10101	刷卡开锁	刷卡开锁
     * 10104	指纹开锁	指纹开锁
     * 10114	人脸开锁	人脸开锁
     * 10118	人证开锁	人证开锁
     * 10119	蓝牙开锁	蓝牙开锁
     * 10120	密码开锁	密码开锁
     * 10122	二维码开锁	二维码开锁
     * 10124	中心平台开锁	远程开门
     * 10125	动态密码开锁	密码开锁
     * @param openType
     * @return
     * OTHER(Short.valueOf ( ( short)0), "其他开门方式"),
     * IC_CARD(Short.valueOf((short)1), "IC卡"),
     * QR_CODE(Short.valueOf((short)2), "二维码"),
     * BLUETOOTH(Short.valueOf((short)3), "蓝牙"),
     * REMOTE(Short.valueOf((short)4), "远程开门"),
     * FACE(Short.valueOf((short)5), "人脸"),
     * MANUAL(Short.valueOf((short)6), "人为开门"),
     * BUTTON(Short.valueOf((short)7), "按钮开门"),
     * PASS_WORD(Short.valueOf((short)8), "密码开门"),
     * FINGERPRINT(Short.valueOf((short)9), "指纹开门");
     */
    private Short handleRecordType(String openType) {
        switch (openType) {
            case "10101":
                return AccessTypeEnum.IC_CARD.getId();
            case "10104":
                return AccessTypeEnum.FINGERPRINT.getId();
            case "10114":
                return AccessTypeEnum.FACE.getId();
            case "10118":
                return AccessTypeEnum.MANUAL.getId();
            case "10119":
                return AccessTypeEnum.BLUETOOTH.getId();
            case "10120":
            case "10125":
                return AccessTypeEnum.PASS_WORD.getId();
            case "10122":
                return AccessTypeEnum.QR_CODE.getId();
            case "10124":
                return AccessTypeEnum.REMOTE.getId();
            default:
                return AccessTypeEnum.OTHER.getId();
        }
    }

    /**
     * 根据社区id找到对应的项目id
     * 处理 一个集团有多个项目需要映射到中台
     * @param config
     * @return map
     * key:海康云眸社区id
     * value：兴海映射项目id
     */
    private Map<String, Integer> handleConfigProjectId(PedestrianIntegrationConfigDTO config) {
        String projectIdKey = HaiKangYunMouConstant.COMMUNITY_ID_AND_PROJECT + config.getProjectId();
        Object obj = redisUtils.get(projectIdKey);
//        Map<String, Integer> projectMap = new HashMap<>();
        if (obj == null) {
            // 处理 一个集团对应多个项目
            String orgIndexCode = config.getOrgIndexCode();
            String orgStr = JSONObject.toJSONString(orgIndexCode);
            Object org = JSON.parse(orgStr);
            String objStr = org.toString();
            List<HaiKangYunMouProject> list = JSONObject.parseArray(objStr, HaiKangYunMouProject.class);
            Map<String, Integer> map = list.stream().collect(
                    Collectors.toMap(HaiKangYunMouProject::getCommunityId, HaiKangYunMouProject::getProjectId));
            redisUtils.setWithMinute(projectIdKey, map, 15);
            return map;
//            if (redisUtils.get(projectIdKey) == null) {
//                return projectMap;
//            }
        }
        return (Map<String, Integer>) obj;
    }

    /**
     * 注意事项：https://pic.hik-cloud.com/opencustom/apidoc/online/neptune/01750d7b6565431988c82d1cdcde964c.html?timestamp=1651824254145
     * 1、创建消费者：5分钟没有消费必须重新获取
     * 2、获取消息通道中消息
     */
    public List<MQConsumerMessagesDTO> getMQMsg(PedestrianIntegrationConfigDTO config) {
        String consumerId = haiKangYunMouUtils.getConsumerId(config);
        List<MQConsumerMessagesDTO> mqMsg = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            mqMsg = haiKangYunMouUtils.getMQMsg(config, consumerId);
            if (!CollectionUtils.isEmpty(mqMsg)) {
                break;
            }
        }
        return mqMsg;
    }


    /**
     * 人员权限(删除)授权
     * @param configDTO 海康请求相关配置
     * @param personIds 海康云眸id
     * @param deviceIds 海康云眸设备id
     */
    public void addAuth(PedestrianIntegrationConfigDTO configDTO, List<String> personIds, List<String> deviceIds,Integer accountId) {
        List<String> communityIds = haiKangYunMouUtils.getCommunityId(configDTO.getProjectId(),accountId);
        if (!CollectionUtils.isEmpty(communityIds)){
            communityIds.forEach(communityId -> {
                haiKangYunMouUtils.batchAuthorityIssued(configDTO, communityId, personIds, deviceIds);
            });
        }

    }
    public void deleteAuth(PedestrianIntegrationConfigDTO configDTO, List<String> personIds, List<String> deviceIds,Integer accountId) {
        List<String> communityIds  =  haiKangYunMouUtils.getCommunityId(configDTO.getProjectId(),accountId);
        for (String personId : personIds) {
            for (String deviceId : deviceIds) {
                if (!CollectionUtils.isEmpty(communityIds)){
                    communityIds.forEach(communityId -> {
                        haiKangYunMouUtils.authorityDelete(configDTO, communityId, personId, deviceId);
                    });
                }
            }
        }
    }
}
